﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// What does this filter mean?
    /// 
    /// Well some per pixel operations for example are very helpful.
    /// But if you like to stack some filters in a macro for realtime processing you 
    /// might loose too much time. So the executtion gets too slow. This is why
    /// you could stack exposed delegates from per pixel filters here, 
    /// to execute them fast. 
    /// </summary>
    public class StackableDelegateFilter : BaseImageFilter
    {
        protected Dictionary<Delegate, object[]> m_aDelegate = new Dictionary<Delegate, object[]>();

        /// <summary>
        /// Initializes a new instance of the <see cref="StackableDelegateFilter"/> class.
        /// </summary>
        public StackableDelegateFilter()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="StackableDelegateFilter"/> class.
        /// </summary>
        /// <param name="_stackableDelegateFilter">The _stackable delegate filter.</param>
        internal StackableDelegateFilter(StackableDelegateFilter _stackableDelegateFilter)
        {
            this.m_aDelegate = _stackableDelegateFilter.m_aDelegate;
        }

        /// <summary>
        /// Gets or sets the delegates.
        /// </summary>
        /// <value>The delegates.</value>
        public Dictionary<Delegate, object[]> Delegates
        {
            get { return m_aDelegate; }
            set { m_aDelegate = value; }
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            foreach (KeyValuePair<Delegate, object[]> keyValuePair in m_aDelegate)
            {
                keyValuePair.Key.DynamicInvoke(keyValuePair.Value);
            }
            return _bitmap;
        }

        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object  Clone()
        {
 	        return new StackableDelegateFilter(this);
        }
    }
}
